"""
编辑操作模块
- 包含倒放、剪切、删除片段、音量调整、变速、淡入/淡出、插入静音等常见编辑功能
- 所有函数遵循输入路径 -> 处理 -> 输出路径的流程
"""

from pydub import AudioSegment
from .base_audio import load_audio, save_audio


def reverse_audio(input_path: str, output_path: str) -> None:
    """
    倒放音频
    """
    audio = load_audio(input_path)
    save_audio(audio.reverse(), output_path)


def cut_audio(input_path: str, output_path: str, start_ms: int, end_ms: int) -> None:
    """
    剪切音频的指定区间 [start_ms, end_ms)
    """
    audio = load_audio(input_path)
    save_audio(audio[start_ms:end_ms], output_path)


def remove_segment(input_path: str, output_path: str, start_ms: int, end_ms: int) -> None:
    """
    删除音频中指定区间 [start_ms, end_ms)，并拼接前后部分
    """
    audio = load_audio(input_path)
    result_audio = audio[:start_ms] + audio[end_ms:]
    save_audio(result_audio, output_path)


def adjust_volume(input_path: str, output_path: str, volume_db: float) -> None:
    """
    按分贝增减音量（正值增大，负值减小）
    """
    audio = load_audio(input_path)
    save_audio(audio + volume_db, output_path)


def change_speed(input_path: str, output_path: str, speed_factor: float) -> None:
    """
    改变播放速度（不改变音调）
    - speed_factor > 1 加速；< 1 减速
    """
    audio = load_audio(input_path)
    adjusted_audio = audio._spawn(audio.raw_data, overrides={
        "frame_rate": int(audio.frame_rate * speed_factor)
    }).set_frame_rate(audio.frame_rate)
    save_audio(adjusted_audio, output_path)


def fade_in(input_path: str, output_path: str, fade_ms: int) -> None:
    """
    添加淡入效果（从静音逐渐到正常音量）
    """
    audio = load_audio(input_path)
    save_audio(audio.fade_in(fade_ms), output_path)


def fade_out(input_path: str, output_path: str, fade_ms: int) -> None:
    """
    添加淡出效果（从正常音量逐渐到静音）
    """
    audio = load_audio(input_path)
    save_audio(audio.fade_out(fade_ms), output_path)


def add_silence(input_path: str, output_path: str, position_ms: int, duration_ms: int) -> None:
    """
    在指定位置插入一段静音

    参数:
        position_ms: 插入位置（毫秒）
        duration_ms: 静音时长（毫秒）
    """
    audio = load_audio(input_path)
    position_ms = max(0, min(len(audio), position_ms))
    silence = AudioSegment.silent(duration=duration_ms)
    result_audio = audio[:position_ms] + silence + audio[position_ms:]
    save_audio(result_audio, output_path)